package com.birdboot.core;

import com.birdboot.annotation.Controller;
import com.birdboot.annotation.RequestMapping;
import com.birdboot.controller.ArticleController;
import com.birdboot.controller.UserController;
import com.birdboot.http.HttpServletRequest;
import com.birdboot.http.HttpServletResponse;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;

/**
 * SpringMVC框架提供的核心类,用于和Tomcat整合,接手处理请求环节的工作
 * <p>
 * 注:
 * HttpServlet是J2EE标准中定义的一个接口,译作:运行在服务端的小程序
 * 该接口中有一个重要的方法:service,用于处理某个请求.
 * 在Tomcat中如果想处理某个请求,我们原本的做法是实现该接口,重写service方法,等待tomcat在
 * 处理请求环节的调用,并得到请求与响应对象,使用请求获取客户端发送信息(比如表单数据等),再利用
 * response给客户端进行回复
 * <p>
 * 由于现在SpringMVC框架接手了处理请求的工作,将繁琐的,冗余的操作封装了起来,因此它如果需要
 * 接收Tomcat处理请求环节的工作,也必须提供一个Servlet,这就是DispatcherServlet的由来
 */
public class DispatcherServlet {
    private static DispatcherServlet instance = new DispatcherServlet();

    private static File baseDir;//类加载路径
    private static File staticDir;//类加载路径下的static目录

    static {
        try {
            baseDir = new File(
                    DispatcherServlet.class.getClassLoader().getResource(".").toURI()
            );
            staticDir = new File(baseDir, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private DispatcherServlet() {
    }

    public static DispatcherServlet getInstance() {
        return instance;
    }

    public void service(HttpServletRequest request, HttpServletResponse response) {
//        String path = request.getUri();
        //使用requestURI来判断请求路径,因为uri中可能含有参数
        String path = request.getRequestURI();
        System.out.println("请求的抽象路径是:" + path);

        //根据请求路径判断是否为处理业务?
        //根据该请求路径提取对应的处理方法
        Method method = HandlerMapping.getMethod(path);
        if(method!=null){//Method不为null说明本次请求是处理业务
            try {
                /*
                    Method中的方法:
                    Class getDeclaringClass()
                    返回的是当前方法所属的类的类对象
                 */
                Class cls = method.getDeclaringClass();
                Object obj = cls.newInstance();//实例化该Controller
                method.invoke(obj,request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            File file = new File(staticDir, path);
            if (file.isFile()) {
                response.setStatusCode(200);
                response.setStatusReason("OK");
                response.addHeader("Server", "BirdServer");
                //设置正文时,该方法中自动添加了Content-Type和Content-Length两个响应头
                response.setContentFile(file);
            } else {
                //404情况
                response.setStatusCode(404);
                response.setStatusReason("NotFound");
                file = new File(staticDir, "404.html");
                response.addHeader("Server", "BirdServer");
                response.setContentFile(file);
            }
        }
    }
}







